package org.example.encrypt.utils;

import cn.hutool.core.util.StrUtil;
import jodd.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author WeiBing
 * @Create 2024/8/12 19:02
 */
public class AESUtil {
    // 定义 aes 加密的key
    // 密钥  必须是16位, 自定义,
    // 如果不是16位, 则会出现InvalidKeyException: Illegal key size
    //  解决方案有两种：
    //1.需要安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files(可以在Oracle下载).
    //2.设置设置key的长度为16个字母和数字的字符窜（128 Bit/8=16字符）就不报错了。
    private static final String key = "=Un[IW;r3Q:|4Kb4";
    //定义加密的编码
    private static final String charset = "utf-8";
    // 偏移量
    private static final int offset = 16;
    private static final String transformation = "AES/CBC/PKCS5Padding";
    private static final String algorithm = "AES";

    /**
     * 加密
     *
     * @param content
     * @return
     */
    public static String encrypt(String content) {
        return encrypt(content, key);
    }

    /**
     * 解密
     *
     * @param content
     * @return
     */
    public static String decrypt(String content) {
        return decrypt(content, key);
    }

    /**
     * 加密
     *
     * @param content 需要加密的内容
     * @param key     加密密码
     * @return
     */
    private static String encrypt(String content, String key) {
        if (StrUtil.isBlank(content)) {
            return content;
        }
        try {
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0, offset);
            Cipher cipher = Cipher.getInstance(transformation);
            byte[] byteContent = content.getBytes(charset);
            cipher.init(Cipher.ENCRYPT_MODE, skey, iv);// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return new Base64().encodeToString(result); // 加密
        } catch (Exception e) {
            // LogUtil.exception(e);
        }
        return null;
    }

    /**
     * AES（256）解密
     *
     * @param content 待解密内容
     * @param key     解密密钥
     * @return 解密之后
     * @throws Exception
     */
    private static String decrypt(String content, String key) {
        if (StrUtil.isBlank(content)) {
            return content;
        }
        try {
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0, offset);
            Cipher cipher = Cipher.getInstance(transformation);
            cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化
            byte[] result = cipher.doFinal(new Base64().decode(content));
            return new String(result); // 解密
        } catch (Exception e) {
            //LogUtil.exception(e);
        }
        return null;
    }

    /**
     * 生成随机的秘钥
     */
    public static String generateSecretKey ( int length){
        if (length < 3) {
            throw new IllegalArgumentException("Key length must be at least 3 to include a number, a letter, and a symbol.");
        }

        // 声明字符取值范围
        final String NUMBERS = "0123456789";
        final String UPPER_LETTER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        final String LOWER_LETTER = "abcdefghijklmnopqrstuvwxyz";
        final String SYMBOLS = "!@#$%^&*()_+-=[]{}|;:,.<>?";

        SecureRandom random = new SecureRandom();
        List<Character> keyChars = new ArrayList<>();

        // 确保秘钥中至少包含一个数字、一个大写字母、一个小写字母和一个符号
        keyChars.add(NUMBERS.charAt(random.nextInt(NUMBERS.length())));
        keyChars.add(UPPER_LETTER.charAt(random.nextInt(UPPER_LETTER.length())));
        keyChars.add(LOWER_LETTER.charAt(random.nextInt(LOWER_LETTER.length())));
        keyChars.add(SYMBOLS.charAt(random.nextInt(SYMBOLS.length())));

        // 填充剩余的秘钥长度
        for (int i = 4; i < length; i++) {
            String allChars = NUMBERS + UPPER_LETTER + LOWER_LETTER + SYMBOLS;
            keyChars.add(allChars.charAt(random.nextInt(allChars.length())));
        }

        // 打乱秘钥中的字符顺序
        for (int i = 0; i < keyChars.size(); i++) {
            int swapWith = random.nextInt(keyChars.size());
            char temp = keyChars.get(i);
            keyChars.set(i, keyChars.get(swapWith));
            keyChars.set(swapWith, temp);
        }

        // 将字符列表转换为字符串
        return keyChars.stream().map(String::valueOf).reduce((a, b) -> a + b).orElse("");
    }

    public static void main(String[] args) {
//        System.out.println(generateSecretKey(16));
        // =Un[IW;r3Q:|4Kb4
//        String s = "222";
//        System.out.println(encrypt(s));
        // K+h1K3jI3NY7GF4vPZk6JQ==

        /*StringBuilder sb = new StringBuilder();
        int x = 16;
        for (int i = 0; i < x; i++) {
            sb.append("哈");
        }
        // 150---620
        // 50---216
        System.out.println(encrypt(sb.toString()).length());*/

        /*AES aes = SecureUtil.aes("=Un[IW;r3Q:|4Kb4".getBytes());
        byte[] encrypt = aes.encrypt("188");
        String s = new String(encrypt);
        System.out.println(s);

        byte[] decrypt = aes.decrypt(s);
        String s1 = new String(decrypt);
        System.out.println(s1);*/

//        System.out.println(encrypt("11011119990602801X"));
//        System.out.println(encrypt("11011119990602801x"));
//        System.out.println(decrypt("AIOKXtOF7bw34DQQZSpua5a9dsT7GWBzl1XN8VqtM0U="));

        /*
        2TV907AwIAFJPmqtSoeQLErGUbssksYUImguNI4Q4rk=
        51Vtgwk/FhvfDRaYhQLhgvSLg/pTNrTT515lFqtNzgc=
        k5OEm8Kuo2PFGwugYUKwRwt6ZXe7T6dbqyM0rgztFpM=
        2E1cfqqFI1j//yvEu1vQadqiKBWJOgrehGlUCFiucoA=
        CGX4LGGYfCsRITLG3qWfPrjveaECyvKRBFAxZD33dQM=
         */
//        System.out.println(decrypt("2TV907AwIAFJPmqtSoeQLErGUbssksYUImguNI4Q4rk="));
//        System.out.println(decrypt("51Vtgwk/FhvfDRaYhQLhgvSLg/pTNrTT515lFqtNzgc="));
//        System.out.println(decrypt("k5OEm8Kuo2PFGwugYUKwRwt6ZXe7T6dbqyM0rgztFpM="));
//        System.out.println(decrypt("2E1cfqqFI1j//yvEu1vQadqiKBWJOgrehGlUCFiucoA="));
//        System.out.println(decrypt("CGX4LGGYfCsRITLG3qWfPrjveaECyvKRBFAxZD33dQM="));

//        System.out.println(encrypt("2TV907AwIAFJPmqtSoeQLErGUbssksYUImguNI4Q4rk="));

        System.out.println(decrypt("HCQZru5l9XhgMG6wLhrin+LC36r1xq+o5ApGpH/uVBU="));

//        String identityCardNumber = "13102419920418502X";
//        String lowerCase = identityCardNumber.toLowerCase();
//        String upperCase = identityCardNumber.toUpperCase();
//        System.out.println(lowerCase);
//        System.out.println(upperCase);

        // 13102419920418502X
//        System.out.println(encrypt("13102419920418502X"));
        // 2TV907AwIAFJPmqtSoeQLErGUbssksYUImguNI4Q4rk=

//        System.out.println(encrypt("13102419920418502x"));
        // 2TV907AwIAFJPmqtSoeQLKkrfjDX3zMqWI/8nBgXwok=
    }

}
